package ru.agiledev.akb.client.panel;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style;
import com.google.gwt.event.dom.client.*;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.*;
import ru.agiledev.akb.client.AKBDataService;
import ru.agiledev.akb.client.AKBDataServiceAsync;
import ru.agiledev.akb.client.AspectKnowledgeBaseApplication;
import ru.agiledev.akb.client.utils.Util;
import ru.agiledev.akb.shared.QType;
import ru.agiledev.akb.shared.TransferObject;

/**
 * Created by a.kirillov
 * Date: 3/24/11 Time: 11:48 PM
 */
public class InputPanel extends VerticalPanel{

    private final AKBDataServiceAsync dataService = GWT.create(AKBDataService.class);

    HorizontalPanel iObjectsPanel;
    HorizontalPanel questionPanel;
    HorizontalPanel qTypePanel;
    VerticalPanel aspectsPanel;
    VerticalPanel examples;
    TextBox iObject1;
    TextBox iObject2;
    TextBox iObject3;
    TextArea questionField;
    ListBox qTypeListBox;
    TextArea aspectsField;
    TextArea examplesText;
    Button save;
    Button cancel;

    Boolean editFlag = false;

    public InputPanel(){
        questionPanel = new HorizontalPanel();
        getElement().getStyle().setPosition(Style.Position.RELATIVE);

        KeyUpHandler iObjectsKeyUpHandler = new iObjectsFieldHandler();
        KeyUpHandler aspectsKeyUpHandler = new aspectsFieldHandler();
        Label questionLabel = new Label("Введите вопрос:");
        questionPanel.add(questionLabel);

        questionField = new TextArea();
        questionField.setWidth("700px");
        questionPanel.add(questionField);
        questionPanel.setHeight("60px");

        questionField.addKeyUpHandler(new QuestionFieldHandler());

        add(questionPanel);


        iObjectsPanel = new HorizontalPanel();
        iObjectsPanel.setVerticalAlignment(HorizontalPanel.ALIGN_MIDDLE);

        Label objectsLabel = new Label("Объекты интереса");
        iObjectsPanel.add(objectsLabel);

        iObject1 = new TextBox();
        iObject1.setEnabled(false);
        iObject1.addKeyUpHandler(iObjectsKeyUpHandler);
        iObjectsPanel.add(iObject1);
        iObjectsPanel.add(iObject1);


        iObject2 = new TextBox();
        iObject2.setEnabled(false);
        iObject2.addKeyUpHandler(iObjectsKeyUpHandler);
        iObjectsPanel.add(iObject2);
        iObjectsPanel.add(iObject2);
        iObjectsPanel.setHeight("30px");

        iObject3 = new TextBox();
        iObject3.addKeyUpHandler(iObjectsKeyUpHandler);
        iObject3.setEnabled(false);
        iObject3.setVisible(false);
        iObjectsPanel.add(iObject3);
        iObjectsPanel.add(iObject3);
        iObjectsPanel.setHeight("30px");


        qTypePanel = new HorizontalPanel();
        qTypePanel.setVerticalAlignment(HorizontalPanel.ALIGN_MIDDLE);

        final Label questionType = new Label("Тип вопроса");
        qTypePanel.add(questionType);
        qTypeListBox = new ListBox();
        qTypeListBox.setEnabled(false);
        qTypeListBox.addItem("Выберите тип вопроса..");

        String[] types = QType.getTypesAsArray();
        for(String type: types){
            qTypeListBox.addItem(type);
        }

        qTypeListBox.addChangeHandler(new ChangeHandler() {
            @Override
            public void onChange(ChangeEvent changeEvent) {

                if(qTypeListBox.getValue(qTypeListBox.getSelectedIndex()).equals("Описание различий")
                        && !iObject3.isVisible()){
                    iObject3.setVisible(true);
                    iObject3.setEnabled(true);
                } else if (iObjectsPanel.getWidgetCount()==4){
                    iObject3.setVisible(false);
                    iObject3.setValue("");

                }

                //form behavior
                if(qTypeListBox.getValue(qTypeListBox.getSelectedIndex()).equals("Выберите тип вопроса..")){

                    if(aspectsField.isEnabled()&&examplesText.isEnabled()){
                        aspectsField.setEnabled(false);
                        examplesText.setEnabled(false);

                        if(save.isEnabled()){
                            save.setEnabled(false);
                        }
                    }
                } else {
                    boolean thirdObject = false;
                    if((iObject3.isVisible()&&(iObject3.getText().length()>0)||(!iObject3.isVisible()))) thirdObject = true;

                    if(((iObject1.getText().length()>0)&&(iObject2.getText().length()>0)&&thirdObject)
                            &&!aspectsField.isEnabled()&&!examplesText.isEnabled()){
                        aspectsField.setEnabled(true);
                        examplesText.setEnabled(true);
                    } else {
                        if(iObject3.isVisible()&&(iObject3.getText().length()==0)){
                            aspectsField.setEnabled(false);
                            examplesText.setEnabled(false);
                        }

                    }
                    if(((aspectsField.getText().length()>0)||(examplesText.getText().length()>0))&&!save.isEnabled()){
                        save.setEnabled(true);
                    }
                }
            }
        });

        qTypePanel.add(qTypeListBox);
        qTypePanel.setHeight("30px");

        add(qTypePanel);
        add(iObjectsPanel);

        aspectsPanel = new VerticalPanel();

        Label aspects = new Label("Аспекты (при вводе разделяйте аспекты запятыми):");
        aspectsPanel.add(aspects);
        aspectsField = new TextArea();
        aspectsField.addKeyUpHandler(aspectsKeyUpHandler);
        aspectsField.setEnabled(false);
        aspectsField.setWidth("774px");

        aspectsPanel.add(aspectsField);
        aspectsPanel.setHeight("80px");

        add(aspectsPanel);

        examples = new VerticalPanel();
        Label exampleLabel = new Label("Примеры (при вводе разделяйте примеры точкой с запятой):");
        examplesText = new TextArea();
        examplesText.addKeyUpHandler(aspectsKeyUpHandler);
        examplesText.setEnabled(false);
        examplesText.setWidth("774px");
        examplesText.setHeight("150px");

        examples.add(exampleLabel);
        examples.add(examplesText);

        add(examples);

        HorizontalPanel saveCancelPanel = new HorizontalPanel();

        save = new Button("Сохранить");
        save.setEnabled(false);
        save.addClickHandler(new saveHandler());
        cancel = new Button("Очистить");

        //TODO: сделать server-side валидацию и дальнейшее сохранение

        // Create the popup dialog box
        final DialogBox dialogBox = new DialogBox();
        dialogBox.setText("Очистить поля");
        dialogBox.setWidth("310px");
        dialogBox.setHeight("100px");
        dialogBox.setModal(true);

        VerticalPanel dialogPanel = new VerticalPanel();
        dialogPanel.setHorizontalAlignment(VerticalPanel.ALIGN_CENTER);


        dialogPanel.add(new HTML("<center><b>Вы уверены, что хотите очистить все поля?</b></center>"));
        HorizontalPanel dialogBoxButtons = new HorizontalPanel();
        dialogBoxButtons.setSpacing(4);
        Button yes = new Button("Да");
        yes.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent clickEvent) {
                if(getParent() instanceof InputPanel){
                    ((InputPanel)getParent()).cleanFields();
                }
                cleanFields();
                dialogBox.hide();
            }
        });

        Button no = new Button("Нет");
        no.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent clickEvent) {
                dialogBox.hide();
            }
        });

        dialogBoxButtons.add(yes);
        dialogBoxButtons.add(no);
        dialogPanel.add(dialogBoxButtons);
        dialogBox.add(dialogPanel);

        cancel.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent clickEvent) {
                dialogBox.setPopupPosition(RootPanel.get().getOffsetWidth()/2-160, RootPanel.get().getOffsetHeight()/2-150);
                dialogBox.show();
            }
        });

        saveCancelPanel.add(save);
        saveCancelPanel.add(cancel);

        saveCancelPanel.setStyleName("saveCancelPanel");

        add(saveCancelPanel);
        setStyleName("tabPanel");
    }

    //Cleaning all current page fields
    public void cleanFields(){
        ((TextArea)questionPanel.getWidget(1)).setText("");
        questionField.setEnabled(true);

        ((ListBox)qTypePanel.getWidget(1)).setItemSelected(0, true);
        ((ListBox)qTypePanel.getWidget(1)).setEnabled(false);

        if (iObjectsPanel.getWidgetCount()==4){
            iObjectsPanel.remove(3);
        }
        ((TextBox)iObjectsPanel.getWidget(2)).setText("");
        ((TextBox)iObjectsPanel.getWidget(2)).setEnabled(false);
        ((TextBox)iObjectsPanel.getWidget(1)).setText("");
        ((TextBox)iObjectsPanel.getWidget(1)).setEnabled(false);

        ((TextArea)aspectsPanel.getWidget(1)).setText("");
        ((TextArea)aspectsPanel.getWidget(1)).setEnabled(false);
        ((TextArea)examples.getWidget(1)).setText("");
        ((TextArea)examples.getWidget(1)).setEnabled(false);
        editFlag = false;
    }


    public class QuestionFieldHandler implements KeyUpHandler{
        @Override
        public void onKeyUp(KeyUpEvent event) {
            if((questionField.getText().length()>10)&&questionField.getText().endsWith("?")&&!editFlag){

                checkForEdit();

                qTypeListBox.setEnabled(true);
                iObject1.setEnabled(true);
                iObject2.setEnabled(true);

                boolean thirdObject = false;
                if((iObject3.isVisible()&&(iObject3.getText().length()>0)||(!iObject3.isVisible()))) thirdObject = true;


                if(!qTypeListBox.getValue(qTypeListBox.getSelectedIndex()).equals("Выберите тип вопроса..")&&((iObject1.getText().length()>0)&&(iObject2.getText().length()>0)&&thirdObject)
                        ||((aspectsField.getText().length()>0)||(examplesText.getText().length()>0))&&!aspectsField.isEnabled()&&!examplesText.isEnabled()){
                    aspectsField.setEnabled(true);
                    examplesText.setEnabled(true);
                    if(!iObject3.isEnabled()&&iObject3.isVisible()){
                        iObject3.setEnabled(true);
                    }

                    if(!save.isEnabled()){
                        save.setEnabled(true);
                    }

                }
            } else {
                if(qTypeListBox.isEnabled()&&iObject1.isEnabled()&&iObject2.isEnabled()&&!editFlag){

                    qTypeListBox.setEnabled(false);
                    iObject1.setEnabled(false);
                    iObject2.setEnabled(false);
                }

                if(aspectsField.isEnabled()&&examplesText.isEnabled()&&!editFlag){
                    aspectsField.setEnabled(false);
                    examplesText.setEnabled(false);

                    if(save.isEnabled()){
                        save.setEnabled(false);
                    }
                }


                if(iObject3.isVisible()&&!editFlag){
                    iObject3.setEnabled(false);
                }
            }
        }
    }

    private void checkForEdit(){
        AsyncCallback<TransferObject> DTOAsyncCallback = new AsyncCallback<TransferObject>() {
            @Override
            public void onFailure(Throwable caught) {
                //TODO: show error window
            }

            @Override
            public void onSuccess(final TransferObject result) {
                if(result!=null){
                    //Filling form' elements
                    editFlag = true;
                    questionField.setEnabled(false);

                    qTypeListBox.setItemSelected(Util.indexOfType(result.getQuestionType())+1, true);
                    qTypeListBox.setEnabled(false);

                    iObject1.setValue(result.getiObjects()[0]);
                    iObject1.setEnabled(false);

                    iObject2.setValue(result.getiObjects()[1]);
                    iObject2.setEnabled(false);
                    if(result.getiObjects().length>2){
                        iObject3.setValue(result.getiObjects()[2]);
                        iObject3.setEnabled(false);
                    }

                    aspectsField.setValue(Util.join(result.getAspects(),", "));
                    aspectsField.setEnabled(true);

                    examplesText.setValue(Util.join(result.getExamples(), "; "));
                    examplesText.setEnabled(true);

                    //Dialog box with description

                    // Create the popup dialog box
                    final DialogBox dialogBox = new DialogBox();
                    dialogBox.setPopupPosition(RootPanel.get().getOffsetWidth()/2-160, RootPanel.get().getOffsetHeight()/2-150);
                    dialogBox.setText("Найдена существующая запись");
                    dialogBox.setWidth("310px");
                    dialogBox.setHeight("100px");
                    dialogBox.setModal(true);

                    VerticalPanel dialogPanel = new VerticalPanel();
                    dialogPanel.setHorizontalAlignment(VerticalPanel.ALIGN_CENTER);


                    dialogPanel.add(new HTML("<center>В базе содержится такой вопрос.\nВы хотите дополнить список аспектов или примеров?</center>"));
                    HorizontalPanel dialogBoxButtons = new HorizontalPanel();
                    dialogBoxButtons.setSpacing(4);
                    Button yes = new Button("Да");
                    yes.addClickHandler(new ClickHandler() {
                        @Override
                        public void onClick(ClickEvent clickEvent) {
                            dialogBox.hide();
                        }
                    });

                    Button no = new Button("Нет");
                    no.addClickHandler(new ClickHandler() {
                        @Override
                        public void onClick(ClickEvent clickEvent) {
                            if(getParent() instanceof InputPanel){
                                ((InputPanel)getParent()).cleanFields();
                            }
                            cleanFields();
                            dialogBox.hide();
                            editFlag = false;
                        }
                    });

                    dialogBoxButtons.add(yes);
                    dialogBoxButtons.add(no);
                    dialogPanel.add(dialogBoxButtons);
                    dialogBox.add(dialogPanel);


                    dialogBox.show();
                    //END Dialog box
                }
            }
        };

        dataService.getDataForQuestion(questionField.getText(), DTOAsyncCallback);




    }

    public class iObjectsFieldHandler implements KeyUpHandler{
        @Override
        public void onKeyUp(KeyUpEvent event) {
            if((iObject1.getText().length()>0)&&(iObject2.getText().length()>0)&&!qTypeListBox.getValue(qTypeListBox.getSelectedIndex()).equals("Выберите тип вопроса..")&&(!iObject3.isVisible()||(iObject3.getText().length()>0))&&!editFlag){
                if(!aspectsField.isEnabled()&&!examplesText.isEnabled()){
                    aspectsField.setEnabled(true);
                    examplesText.setEnabled(true);
                }
                if(((aspectsField.getText().length()>0)||(examplesText.getText().length()>0))&&!save.isEnabled()){
                    save.setEnabled(true);
                }
            } else {

                if(aspectsField.isEnabled()&&examplesText.isEnabled()&&!editFlag){
                    aspectsField.setEnabled(false);
                    examplesText.setEnabled(false);

                    if(save.isEnabled()){
                        save.setEnabled(false);
                    }
                }
            }
        }
    }

    public class aspectsFieldHandler implements KeyUpHandler{
        @Override
        public void onKeyUp(KeyUpEvent event) {
            if((aspectsField.getText().length()>0)&&(examplesText.getText().length()>0)){
                save.setEnabled(true);
            } else {
                save.setEnabled(false);
            }

        }
    }

    public class saveHandler implements ClickHandler{
        @Override
        public void onClick(ClickEvent event) {
            String question = questionField.getText();
                String type = qTypeListBox.getValue(qTypeListBox.getSelectedIndex());
                String[] objects = {iObject1.getText(), iObject2.getText(), iObject3.getText()};

                String[] aspects = aspectsField.getText().split(",");
                String[] examples = examplesText.getText().split(";");

             TransferObject dto = new TransferObject(null, question,
                        QType.fromString(type),
                        objects,
                        aspects,
                        examples,
                        AspectKnowledgeBaseApplication.get().getUser());

            if(!editFlag){

                AsyncCallback<Void> dataSave = new AsyncCallback<Void>() {
                    @Override
                    public void onFailure(Throwable caught) {
                        //TODO: show error message

                    }

                    @Override
                    public void onSuccess(Void result) {
                        final DialogBox dialogBox = new DialogBox();
                        dialogBox.setPopupPosition(RootPanel.get().getOffsetWidth()/2-160, RootPanel.get().getOffsetHeight()/2-150);
                        dialogBox.setText("Данные сохранены");
                        dialogBox.setWidth("310px");
                        dialogBox.setHeight("100px");
                        dialogBox.setModal(true);

                        VerticalPanel dialogPanel = new VerticalPanel();
                        dialogPanel.setHorizontalAlignment(VerticalPanel.ALIGN_CENTER);


                        dialogPanel.add(new HTML("<center>Данные были успешно сохранены.</center>"));
                        HorizontalPanel dialogBoxButtons = new HorizontalPanel();
                        dialogBoxButtons.setSpacing(4);
                        dialogBoxButtons.setHorizontalAlignment(HorizontalPanel.ALIGN_CENTER);
                        Button ok = new Button("Ок");
                        ok.addClickHandler(new ClickHandler() {
                            @Override
                            public void onClick(ClickEvent clickEvent) {
                                dialogBox.hide();
                                cleanFields();
                            }
                        });
                        dialogBoxButtons.add(ok);
                        dialogPanel.add(dialogBoxButtons);
                        dialogBox.add(dialogPanel);
                        dialogBox.show();
                    }

                };

                dataService.saveData(dto, dataSave);
            } else if(editFlag){

                AsyncCallback<Void> dataUpdate = new AsyncCallback<Void>() {
                    @Override
                    public void onFailure(Throwable caught) {
                        //TODO: show error message

                    }

                    @Override
                    public void onSuccess(Void result) {
                        final DialogBox dialogBox = new DialogBox();
                        dialogBox.setPopupPosition(RootPanel.get().getOffsetWidth()/2-160, RootPanel.get().getOffsetHeight()/2-150);
                        dialogBox.setText("Данные сохранены");
                        dialogBox.setWidth("310px");
                        dialogBox.setHeight("100px");
                        dialogBox.setModal(true);

                        VerticalPanel dialogPanel = new VerticalPanel();
                        dialogPanel.setHorizontalAlignment(VerticalPanel.ALIGN_CENTER);


                        dialogPanel.add(new HTML("<center>Данные были успешно сохранены.</center>"));
                        HorizontalPanel dialogBoxButtons = new HorizontalPanel();
                        dialogBoxButtons.setSpacing(4);
                        dialogBoxButtons.setHorizontalAlignment(HorizontalPanel.ALIGN_CENTER);
                        Button ok = new Button("Ок");
                        ok.addClickHandler(new ClickHandler() {
                            @Override
                            public void onClick(ClickEvent clickEvent) {
                                dialogBox.hide();
                                cleanFields();
                            }
                        });
                        dialogBoxButtons.add(ok);
                        dialogPanel.add(dialogBoxButtons);
                        dialogBox.add(dialogPanel);
                        dialogBox.show();
                    }

                };

                dataService.updateData(dto, dataUpdate);

                editFlag = false;
            }
        }
    }
}
